package org.cdc.divination.frame.data;

import org.cdc.divination.frame.data.type.FormatType;
import org.cdc.divination.frame.exception.DataCheckNotPassException;

import java.util.HashMap;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class DeTextFormat {
    public static boolean match(String matchText,String modelText) throws ClassNotFoundException, InstantiationException, IllegalAccessException {
        String[] beMatchedText = matchText.split("\\s");
        String[] beModelText = modelText.split("\\s");
        if (beMatchedText.length > beModelText.length){
            return false;
        }
        for (int index = 0;index<beModelText.length;index++){
            String model = beModelText[index];
            if (index < beMatchedText.length){
                String formatText = beMatchedText[index];
                //如果模块是类型格式
                if (model.matches("\\{[^:]+:.+\\}")){
                    Matcher mt = Pattern.compile("\\{(?<name>[^:]+):(?<type>.+)\\}").matcher(model);
                    mt.find();
                    String name = mt.group("name");
                    String type = mt.group("type");
                    if (!type.contains(".")){type = "org.cdc.divination.frame.data.type"+type;}
                    FormatType formatType = (FormatType) Class.forName(type).newInstance();
                    if (!formatType.checkData(formatText)){
                        return false;
                    }
                } else if (!model.equals(formatText)){
                    return false;
                } else continue;
            } else {
                if (!model.matches("\\{[^:]+:.+\\}")){
                    return false;
                }
            }
        }
        return true;
    }

    String matchText;
    String modelText;
    public DeTextFormat(String matchText,String modelText){
        this.matchText = matchText;
        this.modelText = modelText;
    }

    /**
     * 格式化 条件:模块字符串必须多于被格式化
     * @return 如果不符合条件那么会返回null
     */
    public Map<String,Object> format() throws ClassNotFoundException, InstantiationException, IllegalAccessException, DataCheckNotPassException {
        //得到被格式化字符串
        String[] beMatchedText = matchText.split("\\s");
        //得到模板字符串数组
        String[] beModelText = modelText.split("\\s");
        if (beMatchedText.length > beModelText.length){
            return null;
        }
        Map<String,Object> result = new HashMap<>();
        for (int index = 0;index<beModelText.length;index++){
            String model = beModelText[index];
            if (index < beMatchedText.length){
                String formatText = beMatchedText[index];
                //如果模块是类型格式
                if (model.matches("\\{[^:]+:.+\\}")){
                    Matcher mt = Pattern.compile("\\{(?<name>[^:]+):(?<type>.+)\\}").matcher(model);
                    mt.find();
                    String name = mt.group("name");
                    String type = mt.group("type");
                    if (!type.contains(".")){type = "org.cdc.divination.frame.data.type"+type;}
                    FormatType formatType = (FormatType) Class.forName(type).newInstance();
                    if (!formatType.checkData(formatText)){
                        throw new DataCheckNotPassException("第"+index+"个数据未通过"+formatType.getClass().getSimpleName()+"的数据检查");
                    }
                    result.put(name,formatType.parseData(formatText));
                } else if (!model.equals(formatText)){
                    return null;
                } else continue;
            } else {
                if (model.matches("\\{[^:]+:.+\\}")){
                    Matcher mt = Pattern.compile("\\{(?<name>[^:]+):(?<type>.+)\\}").matcher(model);
                    mt.find();
                    String name = mt.group("name");
                    String type = mt.group("type");
                    FormatType formatType = (FormatType) Class.forName(type).newInstance();
                    result.put(name,formatType.defaultData());
                } else {
                    return null;
                }
            }
        }
        return result;
    }
}
